#ifndef OSCBB_H
#define OSCBB_H

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

#ifdef __linux__
#include <sys/prctl.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/un.h>
#include <ifaddrs.h>
#endif

#include <errno.h>
#include <pthread.h>

#define     SEMHANDLE           pthread_mutex_t *
#define     SOCKHANDLE          int
#define     INVALID_SOCKET      (-1)
#define     TASKHANDLE          pthread_t
#define     TASKID              pthread_t

#ifdef __linux__
#define SOCKADDR_IN             struct sockaddr_in
#ifndef SOCKADDR
    #define SOCKADDR            struct sockaddr
#endif
#endif

/// epoll data
///
#define DMAP_MAX_DATA_LEN   8192

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*FInetDataCb)(void *context, void *buf, int buf_len, uint32_t rmt_ip, uint16_t rmt_port, uint64_t cur_time);
typedef void (*FUnixDataCb)(void *context, void *buf, int buf_len, char *rmt_addr, uint64_t cur_time);
typedef  int (*FTcpDataCb)(void *context, void *buf, int buf_len, uint32_t rmt_ip, uint16_t rmt_port, uint64_t cur_time);
typedef void (*FEvenTrigger)(void *context, uint64_t cur_time);

typedef void (*FSockEpollDealFun)(void *ctx, uint64_t cur_time);

typedef void (*FSockSelectDealFun)(void *ctx, uint64_t cur_time);


typedef struct tagSockEpollCtx
{
    tagSockEpollCtx();
    int                 fd;
    FSockEpollDealFun   func;
    void                *context;
}TSockEpollCtx;


typedef struct tagSockSelectCtx
{
    tagSockSelectCtx();
    int                 fd;
    FSockSelectDealFun  func;
    void                *context;
}TSockSelectCtx;

struct DMapParam
{
    DMapParam();
    uint32_t        svr_addr;               /// 地址
    uint16_t        svr_port;               /// 端口
    FInetDataCb     svr_data_cb;            /// 回调
    void            *svr_data_cb_ctx;       /// 回调用户上下文

    uint32_t        tcp_svr_addr;            /// tcp服务地址
    uint16_t        tcp_svr_port;            /// tcp服务端口
    FTcpDataCb      tcp_svr_data_cb;         /// tcp回调
    void            *tcp_svr_data_cb_ctx;    /// tcp回调用户上下文

    char            inter_msg_addr[64];     /// 内部通信端口,进程内部使用UNIX域UDP通信方式
    FUnixDataCb     inter_msg_cb;           /// 内部消息回调
    void            *inter_msg_cb_ctx;      /// 内部消息回调用户上下文

    FEvenTrigger    event_trigger_cb;       /// 触发器
    void            *ev_trigger_ctx;        /// 触发器用户上下文
};

namespace CBB
{

    /*
     * miliseconds
     */
    uint64_t gettime_ms(void);

    bool cbb_str2l(char *str, long int &val);
    /*
    * safe send
    */
    int  cbb_send(SOCKHANDLE fd, void *buf, int len, int flags = 0, bool block = false);

    /*
    * recv data
    */
    int  cbb_recv(SOCKHANDLE fd, void *buf, int len, int flags = 0);

    /*
    * safe send
    */
    int  cbb_sendto(SOCKHANDLE fd, void *buf, int len, const void *addr, int addr_len, int flags = 0);

    /*
     * recv data
     */
    int  cbb_recvfrom(SOCKHANDLE fd, void *buf, int buf_len, void  *addr = NULL, int *addr_len = NULL, int flags = 0);

    /*
     * socket create & bind
     */
    SOCKHANDLE  cbb_sock_create(int domain, int type, int protocol, int reuse, void *addr, int addr_len);

    SOCKHANDLE  cbb_sock_listen(int fd, int listen_num);

    SOCKHANDLE  cbb_sock_connect(int fd, struct sockaddr *addr);

    SOCKHANDLE  cbb_sock_accept(int fd, struct sockaddr *rmt_addr);

    /*
     * 关闭套接字
     */
    int  cbb_sock_close(SOCKHANDLE handle);

    /*
     * 设置套接字阻塞属性
     */
    int  cbb_socket_nonblock(SOCKHANDLE socket, int enable);


    void get_local_ip(char* ip_buf);



}
#ifdef __cplusplus
}
#endif

#endif // OSCBB_H
